﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{   
    //原型模式：目的是以原型实例创建副本实例，并不需要知道其原始类；也就是说用对象创建对象，而不是用类创建对象，以此达到效率的提升。
    //适用对象：初始化过程比较复杂或者需要消耗大量资源的实例。

    //浅拷贝：只复制原始类型的值到克隆体，而引用类型只复制其引用地址
    //深拷贝：不仅复制原始类型的值到克隆体，引用类型也复制到克隆体中
    public partial class Form1 : Form
    {
        List<EnemyPlane> enemyPlanes = new List<EnemyPlane>();
        public Form1()
        {
            InitializeComponent();         
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int num = 100000;
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            for (int i = 0; i < num; i++)
            {
                enemyPlanes.Add(new EnemyPlane(0, 0));
            }
            sw.Stop();
            MessageBox.Show($"直接new EnemyPlane类需要{sw.ElapsedMilliseconds}ms");
      

            EnemyPlaneFactory.Init();
            sw.Reset();
            sw.Restart();
            for (int i = 0; i < num; i++)
            {
                enemyPlanes.Add(EnemyPlaneFactory.GetEnemyPlane(0, 0));
            }
            sw.Stop();
            MessageBox.Show($"原型克隆EnemyPlane类需要{sw.ElapsedMilliseconds}ms");
        }
    }



    public class EnemyPlane
    {
        int x;
        int y;

        public Bullet Bullet { get; set; }
        public EnemyPlane(int x,int y)
        {
            this.x = x;
            this.y = y;
            Bullet=new Bullet();

            //模仿一些初始化过程
            for (int i = 0; i < 1000; i++)
            {
                if(i<500)
                {
                    this.x++;
                }
                else
                {
                    this.x--;
                }
        
            }
        }

        public EnemyPlane Clone()
        {
           return  (EnemyPlane)this.MemberwiseClone();
        } 

       
    }

    public class Bullet
    {

        public Bullet Clone()
        {
            return (Bullet)this.MemberwiseClone();
        }
    }

    public class EnemyPlaneFactory
    {
        private static EnemyPlane EnemyPlane;
        private static object ob = new object();
        
        public static  void Init()
        {
            if (EnemyPlane == null)
            {
                lock (ob)
                {
                    if (EnemyPlane == null)
                    {
                        EnemyPlane = new EnemyPlane(0, 0);
                    }
                }
            }
        }

        public static EnemyPlane GetEnemyPlane(int x, int y)
        {         
            EnemyPlane res= EnemyPlane.Clone();
            res.Bullet = EnemyPlane.Bullet.Clone();
            return res;
        }
    }

   
}
